<template>
  <div class="max-w-3xl mx-auto p-6">
    <h1 class="text-2xl font-bold mb-4">贪吃蛇（小游戏）</h1>

    <div class="bg-white shadow rounded p-4 mb-6">
      <div class="flex items-center justify-between mb-4">
        <div class="text-sm text-gray-700">得分：<span class="font-medium">{{ score }}</span></div>
        <div class="space-x-2">
          <button @click="startGame" class="px-3 py-1 bg-blue-600 text-white rounded hover:bg-blue-700">开始</button>
          <button @click="pauseGame" class="px-3 py-1 bg-yellow-500 text-white rounded hover:bg-yellow-600">暂停</button>
          <button @click="resetGame" class="px-3 py-1 bg-red-600 text-white rounded hover:bg-red-700">重置</button>
        </div>
      </div>

      <div class="flex justify-center">
        <canvas ref="canvas" :width="width" :height="height" class="border rounded bg-gray-50"></canvas>
      </div>

      <p class="text-sm text-gray-500 mt-3">方向键或 WASD 控制；吃到食物会得分并变长；撞墙或撞到自己游戏结束。</p>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

const width = 400
const height = 400
const cellSize = 20
const cols = Math.floor(width / cellSize)
const rows = Math.floor(height / cellSize)

const canvas = ref(null)

let ctx = null
let timer = null
const intervalMs = ref(120)

const snake = ref([])
const dir = ref({ x: 1, y: 0 })
const food = ref({ x: 0, y: 0 })
const score = ref(0)
const running = ref(false)

function randCell() {
  return {
    x: Math.floor(Math.random() * cols),
    y: Math.floor(Math.random() * rows)
  }
}

function placeFood() {
  let p
  do {
    p = randCell()
  } while (snake.value.some(s => s.x === p.x && s.y === p.y))
  food.value = p
}

function init() {
  snake.value = [ { x: Math.floor(cols/2), y: Math.floor(rows/2) } ]
  dir.value = { x: 1, y: 0 }
  score.value = 0
  placeFood()
}

function draw() {
  if (!ctx) return
  ctx.clearRect(0,0,width,height)
  // 背景网格（可选）
  // 绘制食物
  ctx.fillStyle = '#ef4444'
  ctx.fillRect(food.value.x * cellSize, food.value.y * cellSize, cellSize, cellSize)

  // 绘制蛇
  ctx.fillStyle = '#10b981'
  for (let i = 0; i < snake.value.length; i++) {
    const s = snake.value[i]
    ctx.fillRect(s.x * cellSize, s.y * cellSize, cellSize - 1, cellSize - 1)
  }
}

function step() {
  if (!running.value) return
  const head = { x: snake.value[0].x + dir.value.x, y: snake.value[0].y + dir.value.y }

  // 碰墙检测
  if (head.x < 0 || head.x >= cols || head.y < 0 || head.y >= rows) {
    gameOver()
    return
  }

  // 碰自己
  if (snake.value.some(s => s.x === head.x && s.y === head.y)) {
    gameOver()
    return
  }

  snake.value.unshift(head)

  // 吃到食物
  if (head.x === food.value.x && head.y === food.value.y) {
    score.value += 1
    placeFood()
  } else {
    snake.value.pop()
  }

  draw()
}

function gameOver() {
  running.value = false
  clearInterval(timer)
  timer = null
  alert('游戏结束！得分：' + score.value)
}

function startGame() {
  if (running.value) return
  if (!snake.value.length) init()
  running.value = true
  if (timer) clearInterval(timer)
  timer = setInterval(step, intervalMs.value)
}

function pauseGame() {
  running.value = false
  if (timer) { clearInterval(timer); timer = null }
}

function resetGame() {
  pauseGame()
  init()
  draw()
}

function handleKey(e) {
  const k = e.key
  if (['ArrowUp','w','W'].includes(k) && dir.value.y !== 1) { dir.value = { x: 0, y: -1 } }
  if (['ArrowDown','s','S'].includes(k) && dir.value.y !== -1) { dir.value = { x: 0, y: 1 } }
  if (['ArrowLeft','a','A'].includes(k) && dir.value.x !== 1) { dir.value = { x: -1, y: 0 } }
  if (['ArrowRight','d','D'].includes(k) && dir.value.x !== -1) { dir.value = { x: 1, y: 0 } }
}

onMounted(() => {
  const c = canvas.value
  if (c) ctx = c.getContext('2d')
  init()
  draw()
  window.addEventListener('keydown', handleKey)
})

onUnmounted(() => {
  pauseGame()
  window.removeEventListener('keydown', handleKey)
})

</script>

<style scoped>
canvas { max-width: 100%; height: auto; }
</style>
